#!/usr/bin/env python2
#-*- coding: utf-8 -*-

import logging
import logging.handlers
import json
import os

from Ump.common import config

from Ump import utils

log_map = {}

class NullHandler(logging.Handler):
    def emit(self, record):
        pass

class MessageFilter(logging.Filter):
    '''
    把需要的消息放在DB中, 如果record有skipmf属性就不进行处理
    TODO: 处理数据库异常时可以不影响写入日志文件
    '''
    def filter(self, record):
        if 'skipmf' in dir(record):
            return True

        insert_db = ('WARNING', 'ERROR', 'CRITICAL')
        #insert_db = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
        level = record.levelname

        if level in insert_db:
            #为了防止html的解释
            message = record.getMessage().replace('<', '< ')
            extra = {}
            for i in dir(record):
                if not i.startswith('_'):
                    extra.update({i: str(getattr(record, i))})
            values = {
                    'level': level,
                    'event': record.name,
                    'info': message,
                    'extra': json.dumps(extra),
                    }
            if 'cluster_id' in dir(record):
                values.update({'cluster_id': record.cluster_id})
            if 'vpool_id' in dir(record):
                values.update({'vpool_id': record.vpool_id})

            #message_create(values)
        return True


def get_log(log_name):
    """
        log_name,日志系统的名称
        return my_logger:
        note:
        如果在配置DEBUG为True，hander的级别为DEBUG，
        否则，配置的级别是INFO
        EVELS = {'debug': logging.DEBUG,
                 'info': logging.INFO,
                 'warning': logging.WARNING,
                 'error': logging.ERROR,
                 'critical': logging.CRITICAL}
    """
    my_logger = log_map.get(log_name)
    if my_logger is not None:
        return my_logger

    log_file = config.main_log
    log_dir = os.path.dirname(log_file)
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir)

    logging.addLevelName(25,"EVENT")
    my_logger = logging.getLogger(log_name)
    if 'DEBUG' in dir(config) and getattr(config, 'DEBUG'):
        my_logger.setLevel(logging.DEBUG)
    else:
        my_logger.setLevel(logging.INFO)

    my_logger.addFilter(MessageFilter())
    handler = logging.handlers.RotatingFileHandler(
        log_file, 
        maxBytes = config.main_log_maxbytes,
        backupCount=config.main_log_backupCount)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
            "%(asctime)s-%(name)s-%(levelname)s-%(message)s")
    handler.setFormatter(formatter)
    my_logger.addHandler(handler)

    log_map.update({log_name:my_logger})
    return my_logger

def get_history_log():
    log_name = 'history'

    log_file = config.history_log
    log_dir = os.path.dirname(log_file)
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir)

    h_logger = log_map.get(log_name)
    if h_logger is not None:
        return h_logger

    h_logger = logging.getLogger(log_name)
    h_logger.setLevel(logging.INFO)
    handler = logging.handlers.RotatingFileHandler(
        log_file,  
        maxBytes = config.history_log_maxbytes,
        backupCount=config.history_log_backupCount)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
      "%(asctime)s-%(message)s")
    handler.setFormatter(formatter)
    h_logger.addHandler(handler)
    log_map.update({log_name: h_logger})
    return h_logger

def log_init():
    logging.getLogger("Ump").addHandler(NullHandler())
    logging.getLogger("Ump").addFilter(MessageFilter())

import os.path  
import logging  
from mlogging import FileHandler_MP, TimedRotatingFileHandler_MP, RotatingFileHandler_MP 
from functools import partial  
  
  
class LevelFilter(logging.Filter):  
  
    def __init__(self, level, *args, **kwargs):  
        #super(LevelFilter, self).__init__(*args, **kwargs)  
        self.level = level  
  
    def filter(self, record):  
        return record.levelno == self.level  
  
  
def init_info_logger(name='Ump', logging_file=config.controller_log):
    handler = RotatingFileHandler_MP(
                logging_file, 
                maxBytes=config.controller_log_maxbytes, 
                backupCount=config.controller_log_backupCount)
    handler.setFormatter( logging.Formatter(  
        "%(asctime)s-%(name)s-%(levelname)s-%(message)s",
        datefmt = "%Y-%m-%d %H:%M:%S" 
    ))  
    handler.suffix = "%Y%m%d"  
  
    logger = logging.getLogger(name)  
    logger.setLevel(logging.INFO)  
    extra={"clientip":"-", "user":"-"}  
    setattr(logger, "info", partial(logger.info, exc_info=False, extra=extra))  
    logger.addHandler( handler )  
    return logger  
  
  
def init_error_logger(logging_dir):  
    logging_file = os.path.join(logging_dir, "errors.log")  
    handler = FileHandler_MP(logging_file)  
    handler.setFormatter( logging.Formatter(  
        "%(asctime)s %(levelname)-8s %(message)s", 
        datefmt = "%Y-%m-%d %H:%M:%S"
    ))  
  
    logger = logging.getLogger()  
    logger.setLevel(logging.WARNING)  
    extra={"clientip":"-", "user":"-"}  
    setattr(logger, "critical", partial(logger.critical, exc_info=True, extra=extra))  
    setattr(logger, "error", partial(logger.error, exc_info=True, extra=extra))  
    setattr(logger, "warning", partial(logger.warning, exc_info=True, extra=extra))  
    logger.addHandler( handler )  
    return logger  

def get_logger(name):
    return logging.getLogger(name)


if __name__ == '__main__':
    '''for test'''
    logger = init_info_logger()
    logger.error("test")  
